package com.fc.push;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.json.JSONArray;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fc.commons.security.MD5Util;
import com.fc.persistence.cache.redis.SharedJedisFacade;
import com.fc.persistence.core.ITranscation;
import com.fc.persistence.core.TranscationImpl;
import com.fc.persistence.dao.DAOTemplate;
import com.fc.push.db.entities.Application;
import com.fc.push.handler.pub.service.APNsPublishUtil;
import com.fc.push.logger.Applogger;
import com.fc.push.mqtt.SharedMqttClientPoolFacade;
import com.fc.remoting.TcpRemotingServerImpl;

import javapns.notification.PushNotificationPayload;

public class App implements ServletContextListener {
	private static ApplicationContext context = null;

	private static TcpRemotingServerImpl service = null;

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		context = new ClassPathXmlApplicationContext("appContext.xml");
		// initMqttJedisPool
		SharedJedisFacade.initJedisPool();
		// initMqttClientPool
		SharedMqttClientPoolFacade.initPoolImpl();
		try {
			if (!initMonitor()) {
				System.exit(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
		// 启动tcp服务
		run();
	}

	private boolean initMonitor() throws IOException {

		int monitorPort = ServerConfig.getMonitorport();
		if(monitorPort == -1){
			return true;
		}
		HttpClient client = new HttpClient();
		// pass our credentials to HttpClient, they will only be used for
		// authenticating to servers with realm "realm" on the host
		// "www.verisign.com", to authenticate against
		// an arbitrary realm or host change the appropriate argument to null.
		client.getState().setCredentials(new AuthScope(ServerConfig.getMonitorhost(), monitorPort),
				new UsernamePasswordCredentials("monitor", "monitoradmin"));
		// create a GET method that reads a file over HTTPS, we're assuming
		// that this file requires basic authentication using the realm above.
		GetMethod get = new GetMethod(ServerConfig.getMonitorregisterurl());
		// Tell the GET method to automatically handle authentication. The
		// method will use any appropriate credentials to handle basic
		// authentication requests. Setting this value to false will cause
		// any request for authentication to return with a status of 401.
		// It will then be up to the client to handle the authentication.
		get.setDoAuthentication(true);

		// execute the GET
		int status = client.executeMethod(get);
		if (status==200 && get.getResponseBodyAsString().equals("success")) {
			return true;
		}

		return false;
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// 关闭jedis链接池
		SharedJedisFacade.closeJedisPool();
		// 关闭mqttclient链接池
		SharedMqttClientPoolFacade.closeMqttClientPool();

		// 关闭tcp服务
		service.shutdown();
	}

	public static ApplicationContext getContext() {
		if (context == null) {
			throw new IllegalAccessError("context初始化失败");
		}
		return context;
	}

	public static Object getBean(Class<?> clazz) {
		if (context == null) {
			throw new IllegalAccessError("context初始化失败");
		}
		return context.getBean(clazz.getSimpleName().toLowerCase());
	}

	private static void run() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				TcpRemotingServerImpl service = (TcpRemotingServerImpl) context.getBean(TcpRemotingServerImpl.class);
				try {
					service.start(ServerConfig.getTport());
				} catch (Exception e) {
					Applogger.instance().getLogger().debug(e.getMessage(), e);
				}
			}
		}).start();
	}

	/**
	 * ios推送测试
	 */
	private static void testIOSPublish() {
		if (context == null) {
			context = new ClassPathXmlApplicationContext("appContext.xml");
		}
		ITranscation transcation = (ITranscation) App.getBean(TranscationImpl.class);
		
		//测试机测试
		//String appkey = "4c6cc04796434f8d9e6e3efe80311f3c";
		//String deviceToken = "d92ee4e29456b9927cea44748d42919b280efc9ded33e309566d0bacfcfeed8d";
		
		
		
//		String appkey = "4d9b36ffde2746f9a38a08e2e1a1b1c5";
		
		String deviceToken = "feb02cad7e208e1a0b6c52305ca848e395b326bef5a5f9bc59ef931b267f1dcc";
		
		
		
//		String sql_app = "from " + Application.class.getSimpleName() + " where appkey = '" + appkey + "'";
//		List<DAOTemplate> applist = transcation.getBySQL(sql_app);
//		if (applist == null || applist.size() == 0) {
//			System.out.println("appkey is not exist application");
//		}
		
		
		String filename = "C:\\Users\\Administrator\\Desktop\\p12证书\\p12证书\\sstore_push_pro.p12";
				
		File file=new File(filename);//要识别的文件路径
		byte[] filedata = null;
		try {
			 filedata = file2byte(file);
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
//		Application application = (Application) applist.get(0);
		
//		application.setFile(filedata);
//		transcation.save(application);
		
		
		
		JSONObject payloadJson = new JSONObject();
		JSONObject apsJson = new JSONObject();
		apsJson.put("id", "");
		apsJson.put("type", "im");
		apsJson.put("extras", new JSONArray());
		payloadJson.put("aps", apsJson);
		
		
		
		PushNotificationPayload payload = null;
		
		
		try {
			payload = new PushNotificationPayload(payloadJson.toJSONString());
		} catch (org.json.JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			payload.addAlert("您有一条新消息xxxxx");
			payload.addBadge(1);//
			payload.addSound("001.wav");

		} catch (JSONException e) {
			e.printStackTrace();
		} catch (org.json.JSONException e) {
			e.printStackTrace();
		}
		// 是否是生产环
//		boolean isProduction = false;
//		if (application.getIsproduction() == 1) {
//			isProduction = true;
//		}
		new APNsPublishUtil().pubMessageBySlice(filedata,"123456", payload, true,
				deviceToken);
		
//		new APNsPublishUtil().pubMessageBySlice(filedata, application.getPwd(), payload, isProduction,
//				deviceToken);
	}
	public static byte[] file2byte(File file) throws IOException {
		byte[] bytes = null;
		if (file != null) {
			InputStream is = new FileInputStream(file);
			int length = (int) file.length();
			if (length > Integer.MAX_VALUE) // 当文件的长度超过了int的最大值
			{
				System.out.println("this file is max ");
				return null;
			}
			bytes = new byte[length];
			int offset = 0;
			int numRead = 0;
			while (offset < bytes.length&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
				offset += numRead;
			}
			// 如果得到的字节长度和file实际的长度不一致就可能出错了
			if (offset < bytes.length) {
				System.out.println("file length is error");
				return null;
			}
			is.close();
		}
		return bytes;
	}
	public static void main(String[] args) {
		testIOSPublish();

		String clientid = MD5Util.Instance.getInstance()
				.md5TO23Bit("81bdf6f5b66e47989bfc365a0e221daf" + "e0cb7f78e88804ca");
		System.out.println(clientid);
	}
}
